package cn.remex.contrib.service;

import cn.remex.RemexConstants;
import cn.remex.contrib.SyncUserRoleEvent;
import cn.remex.contrib.SysRoleEvent;
import cn.remex.contrib.appbeans.DataCvo;
import cn.remex.contrib.appbeans.DataRvo;
import cn.remex.core.RemexApplication;
import cn.remex.core.RemexContext;
import cn.remex.core.exception.ServiceCode;
import cn.remex.core.util.Assert;
import cn.remex.core.util.Judgment;
import cn.remex.core.util.MapHelper;
import cn.remex.db.Database;
import cn.remex.db.DbCvo;
import cn.remex.db.DbRvo;
import cn.remex.db.model.*;
import cn.remex.db.rsql.connection.RDBManager;
import cn.remex.db.rsql.connection.RDBSpaceConfig;
import cn.remex.db.rsql.transactional.RsqlTransaction;
import cn.remex.web.aspect.BusinessServiceAspect;
import cn.remex.web.service.BsRvo;
import cn.remex.web.service.BusinessService;
import cn.remex.wechat.WeChat;
import cn.remex.wechat.models.WeChatUser;
import org.logicalcobwebs.proxool.ProxoolDataSource;
import java.util.List;

import static cn.remex.RemexConstants.OperateType.DELETE;
import static cn.remex.RemexConstants.OperateType.UPDATE;
import static cn.remex.db.sql.WhereRuleOper.equal;
import static cn.remex.web.service.BusinessService.ServiceRole.admin;
import static cn.remex.web.service.BusinessService.ServiceRole.user;

/** 
 * @author liuhengyang 
 * date 2015-8-29 下午6:20:59
 * @version 版本号码
 */
@BusinessService
public class AdminService {
//    //初始化项目使用的
//    @BusinessService
//    public BsRvo addDefaultMenu(boolean delold) {
//
//        if(delold){
//            Database.getSession().execute("delete from `SysMenu`",new HashMap<>());
//        }
//
//        SysMenu menu = new SysMenu();
//        menu.setOpened(true);
//        menu.setParentFlag(true);
//        menu.setNodeName("root");
//        Database.getSession().store(menu);
//        SysMenu root = menu;
//
//        menu = new SysMenu();
//        menu.setParentFlag(true);
//        menu.setIcon("fa-dashboard");
//        menu.setNodeName("系统配置");
//        menu.setSupMenu(root);
//        Database.getSession().store(menu);
//        SysMenu xtpz = menu;
//
//        menu = new SysMenu();
//        menu.setIcon("fa-user");
//        menu.setNodeName("用户");
//        menu.setSupMenu(xtpz);
//        Database.getSession().store(menu);
//
//        menu = new SysMenu();
//        menu.setIcon("fa-users");
//        menu.setNodeName("角色");
//        menu.setSupMenu(xtpz);
//        Database.getSession().store(menu);
//
//        return new BsRvo(true);
//	}

    //系统配置页
    @BusinessService(name = "重置权限明细设置")
    public BsRvo resetSysUris() {//重置权限
        Object sysUris = RemexContext.resetAuthority();
        return new BsRvo(ServiceCode.SUCCESS, "重构默认URI权限成功,系统不会删除手动配置的URI,但会将系统默认的URI信息更新", sysUris);
    }

    @BusinessService(name = "重构数据结构")
	public BsRvo resetDb(boolean resetDb) {//重构数据库
        RDBManager.reset(resetDb);
        return new BsRvo(ServiceCode.SUCCESS,"OK",resetDb?"重构数据库成功":"清理数据库缓存成功");
	}
    @BusinessService(name = "重置服务缓存", authRoles = admin)
	public BsRvo databaseInfo() {//数据库信息
        return new BsRvo(ServiceCode.SUCCESS,"OK", MapHelper.toMap("driverUrl",((ProxoolDataSource) RDBManager.getLocalSpaceConfig().getDataSource()).getDriverUrl()));
	}
    @BusinessService(name = "重置服务缓存", authRoles = admin)
	public BsRvo resetBsCache() {//重构数据库
        BusinessServiceAspect.resetCache();
        return new BsRvo(ServiceCode.SUCCESS, "OK");
    }
    @BusinessService(name = "获取数据bean列表")
	public Object ormBeans(String spaceName) {//获取数据bean列表
        RDBSpaceConfig spaceConfig = RDBManager.getLocalSpaceConfig(Judgment.nullOrBlank(spaceName) ? RDBManager.DEFAULT_SPACE : spaceName);
        return spaceConfig.getOrmBeans();
	}

    //角色页面
    @BusinessService(name = "获取角色列表", authRoles = admin)
    public BsRvo roles(DataCvo bsCvo){
        DbCvo<SysRole,?> dbCvo = bsCvo.obtainDbCvo(SysRole.class).withBase()
           //.withList(SysRole::getMenus).withList(SysRole::getSysUris)
            ;
        DbRvo dbRvo = dbCvo.ready().query();
        return new DataRvo(dbRvo);
    }
    @BusinessService(name = "保存角色")
    public BsRvo saveRole(SysRole role){
        DbRvo dbRvo = Database.getSession().store(role);
        //发布异步事件，同步角色信息到activiti
        RemexApplication.publishEvent(new SysRoleEvent("updateUserRole", UPDATE, role));
        return new BsRvo(ServiceCode.SUCCESS,"",role);
    }
    @BusinessService(name = "删除角色")
    public BsRvo delRole(SysRole role){
        Assert.isTrue(!Judgment.nullOrBlank(role.getName()) && !"root,user,admin".contains(role.getName().trim()),ServiceCode.FAIL,"系统核心角色不能删除！");
        DbRvo dbRvo = Database.getSession().delete(role);
        //发布异步事件，同步角色信息到activiti
        RemexApplication.publishEvent(new SysRoleEvent("updateUserRole", DELETE, role));
        return new BsRvo(dbRvo.getEffectRowCount()==1? ServiceCode.SUCCESS: ServiceCode.FAIL,dbRvo.getMsg());
    }
    @BusinessService(name = "删除角色")
    public BsRvo roleUris(String pk){
        return new DataRvo(Database.createDbCvo(SysRole.class).ready().queryCollectionField(SysRole::getSysUris, pk));
    }
    @BusinessService(name = "角色的菜单")
    public BsRvo roleMenus(String pk){
        return new DataRvo(Database.createDbCvo(SysRole.class).ready().queryCollectionField(SysRole::getMenus, pk));
    }
    @BusinessService(name = "角色的块")
    public BsRvo roleBlocks(String pk){
        return new DataRvo(Database.createDbCvo(SysRole.class).ready().queryCollectionField(SysRole::getBlocks, pk));
    }
    @BusinessService(name = "角色归属的组织机构")
    public BsRvo roleOrganizations(String pk){
        return new DataRvo(Database.createDbCvo(SysRole.class).ready().queryCollectionField(SysRole::getSysDepts, pk));
    }
    @BusinessService(name = "组织机构明细")
    public BsRvo organizations(DataCvo bsCvo){//所有组织机构
        DbCvo<SysDept,?> dbCvo = bsCvo.obtainDbCvo(SysDept.class);
        return new DataRvo(dbCvo.ready().query());
    }
    @BusinessService(name = "功能权限明细")
    public BsRvo uris(DataCvo bsCvo){//功能权限
        DbCvo<SysUri,?> dbCvo = bsCvo.obtainDbCvo(SysUri.class);
        return new DataRvo(dbCvo.ready().query());
    }

    //用户页面
    @BusinessService(name = "用户明细")
    public BsRvo users(DataCvo bsCvo){
        DbCvo<SysUser,?> dbCvo = bsCvo.obtainDbCvo(SysUser.class);
        return new DataRvo(dbCvo/*.rowCount(1000)*/.ready().query());
    }
    @BusinessService(name = "保存用户")
    public BsRvo saveUser(SysUser user){
        if(Judgment.nullOrBlank(user.getId()))//新用户进行检查
            Assert.isNull(Database.createDbCvo(SysUser.class).filterBy(SysUser::getUsername, equal,user.getUsername()).ready().queryBean(), ServiceCode.FAIL,"该用户已经被注册!");

        if (user.getUserType() == null) {
            user.setUserType(RemexConstants.UserType.C_USER);
        }

        DbRvo dbRvo = Database.getSession().store(user);
        //发布异步事件，同步角色信息到activiti
        RemexApplication.publishEvent(new SyncUserRoleEvent("updateUserRole", user));
        return new BsRvo(ServiceCode.SUCCESS,"OK",user);
    }
    @BusinessService(name="删除角色")
	public BsRvo delUser(SysUser role) {
		SysUser au = Database.createDbCvo(SysUser.class).filterById(role.getId()).ready().queryBean();
        Assert.isTrue(!"admin".equals(au.getUsername()), ServiceCode.FAIL,"系统用户不得删除！");
        DbRvo dbRvo = Database.getSession().delete(role);
        return new BsRvo(dbRvo.getEffectRowCount()==1? ServiceCode.SUCCESS: ServiceCode.FAIL,dbRvo.getMsg());
	}
    @BusinessService(name="指定用户的角色")
    public BsRvo rolesOfUser(String pk){
        return new DataRvo(Database.createDbCvo(SysUser.class).ready().queryCollectionField(SysUser::getRoles, pk));
    }
    @BusinessService(name = "解除微信绑定") @RsqlTransaction
    public BsRvo unbindWeChat(String userId){
        Assert.notNull(userId, ServiceCode.FAIL, "解绑用户微信时,用户Id不能为空");
        Database.update(WeChatUser.class)
                .filterBy(WeChatUser::getSysUser, equal, userId)
                .assignNull(WeChatUser::getSysUser)
                .execute().assertTrue(rvo->rvo.getEffectRowCount()<10,ServiceCode.FAIL, "解绑用户微信更新用户微信信息失败");//一个微信最多关联十个用户
        return new BsRvo(ServiceCode.SUCCESS, "解绑成功");
    }


    //菜单页面
    @BusinessService(name = "保存角色")
    public BsRvo saveMenu(SysMenu menu){
        DbRvo dbRvo = Database.getSession().store(menu);
        return new BsRvo(ServiceCode.SUCCESS,"OK",MapHelper.toMap("id",menu.getId()));
    }
    @BusinessService(name = "删除菜单")
    public BsRvo delMenu(SysMenu menu) {
        DbRvo dbRvo = Database.getSession().delete(menu);
        return new BsRvo(dbRvo.getEffectRowCount()==1? ServiceCode.SUCCESS: ServiceCode.FAIL,dbRvo.getMsg());
    }
    @BusinessService(name = "菜单列表")
    public BsRvo menus(DataCvo bsCvo){
        DbCvo<SysMenu,?> dbCvo = bsCvo.obtainDbCvo(SysMenu.class).withBase()
                .withModel(SysMenu::getSupMenu,s->s.withModel(SysMenu::getSupMenu,s1->s1.withModel(SysMenu::getSupMenu)));
        return new DataRvo(dbCvo.ready().query());
    }

    //数据字典
    @BusinessService(name = "数据字典列表")
    public DataRvo sysCode(DataCvo dataCvo) {
        DbCvo<SysCode,?> dbCvo = dataCvo.obtainDbCvo(SysCode.class).withBase();
        return new DataRvo(dbCvo.ready().query());
    }
    @BusinessService(name = "保存字典")
    public SysCode saveSysCode(SysCode sysCode) {
        DbRvo dbRvo = Database.getSession().store(sysCode);
        return sysCode;
    }
    @BusinessService(name = "删除字典")
    public BsRvo delSysCode(SysCode sysCode) {
        DbRvo dbRvo = Database.getSession().delete(sysCode);
        return new BsRvo(dbRvo.getEffectRowCount() == 1? ServiceCode.SUCCESS: ServiceCode.FAIL, dbRvo.getMsg());
    }

}
